package com.blog.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Aspect
@Component
public class TimeAspect {
    private static Logger log= LoggerFactory.getLogger(TimeAspect.class);
    /**
     * @Pointcut注解用于定义切入点，切入点的内容可以是一些表达式，我们
     * 这个案例中先使用一个注解表达式。后续我们可以使用注解表达式中的
     * 注解描述切入点方法，通过通知方法为切入点方法进行功能拓展。
     */
    @Pointcut("@annotation(com.blog.annotation.RequiredTime)")
    public void doTime(){}//doTime没有实际意义，方法体中不用写内容，只是为了承载注解的定义


    /**
     * @Around注解描述的方法为一个环绕通知方法，此方法内部可以手动调用目标执行链，
     * 并且在目标执行链之前或之后添加一些扩展业务逻辑。
     * @param joinPoint 连接节点-封装了目标切入点方法信息
     * @return
     * @throws Throwable
     */
    @Around("doTime()")
    public Object doTimeAround(ProceedingJoinPoint joinPoint)throws Throwable{
        log.info("@Around.Before {}", LocalDateTime.now());
        Object result=joinPoint.proceed();//调用目标执行链(可以有当前类的其它通知方法+其它切面中的通知方法+目标业务方法)
        log.info("@Around.After {}",LocalDateTime.now());
        return result;
    }

    //....

}
